home *** CD-ROM | disk | FTP | other *** search
- /*
- * Yamana's Otomeza Plug-in Tool
- * スプライン曲線
- *
- * 1995.08.20 2次関数を用いた補完
- * 1995.08.27 スプライン法に変更
- *
- * 問題点
- * ・汚いソースである(^^;)
- *
- */
- #include "otome_pi.h"
-
- const char longname[] = "DRAW : スプライン曲線";
- int cnfg_max = 1;
- PI_CNFG cnfg[] = {
- {"線の太さ" , 1, 32, 1, 1 }
- };
-
- #define USE_ENV PI_SET_ENV
- #define USE_TYPE PI_EFFC_POLY
- #include "otome_pi.c"
-
- typedef struct
- {
- short x,y;
-
- }Points;
-
- /*******************************************************/
-
- int num;
-
- int mk_spTbl( x,y,f )
- double *x,*f;
- int *y;
- {
- int i;
- double t,*h,*d;
-
- if( (h=(double *)PI_MALLOC( sizeof(double)*num*2 ))==NULL )
- return ERROR;
- d = &h[ num ];
-
- f[0] = f[num-1] = 0;
- for( i=0; i<num-1; i++ )
- {
- h[i ] = (x[i+1] - x[i]);
- d[i+1] = (y[i+1] - y[i]) / h[i];
- }
-
- f[1] = d[2] - d[1];
- d[1] = (x[2] - x[0])*2 ;
- for( i=1; i<num-2; i++ )
- {
- t = (h[i] / d[i]);
- f[i+1] = (d[i+2] - d[i+1]) - f[i] * t;
- d[i+1] = (x[i+2] - x[i ])*2 - h[i] * t;
- }
- f[num-2] -= h[num-2]*f[num-1];
- for( i=num-2; i>0; i-- )
- f[i] = (f[i] - h[i] * f[i+1]) / d[i];
-
- return NOERR;
- }
-
- int get_sp( t,x,y,f )
- double *x,*f;
- int t,*y;
- {
- int i,j,k;
- int d,h;
-
- i=0,j=num-1;
- while( i<j )
- { k = (i+j)/2;
- if( x[k] < t ) i = k+1;
- else j = k;
- }
- if( i>0 ) i--;
-
- h = (x[i+1] - x[i]);
- d = ( t - x[i]);
-
- return (
- ((f[i+1] - f[i])* d * 256 / h + f[i] * 3 *256 ) * d
- + ((y[i+1] - y[i]) * 256 / h - (f[i] * 2 + f[i+1])* h*256 )
- ) * d /256 + y[i];
-
- }
-
- int spline( pp )
- Points *pp;
- {
- int i;
- int x0,y0,x1,y1,step;
- int t0,t1,*x,*y;
- double *l,*a,*b;
-
- LINE line;
- line.n = 2;
-
- /* double=64bit,int=32bit */
- if( (l=(double *)PI_MALLOC( sizeof(double)*num*4 ))==NULL )
- return PI_ERROR_NO_MEMORY;
- a = &l[num];
- b = &a[num];
- x = (int*)&b[num];
- y = (int*)&x[num];
-
- for( i=0; i<num ; i++)
- { x[i] = pp[i].x;
- y[i] = pp[i].y;
- }
- l[0] = 0;
- for( i=1; i<num; i++ ) /* 始点からの総距離 */
- { t0 = x[i] - x[i-1];
- t1 = y[i] - y[i-1];
- l[i] = l[i-1] + (int)sqrt( t0*t0 + t1*t1 );
- }
- mk_spTbl( l, x, a );
- mk_spTbl( l, y, b );
-
- /* 速度と精度のバランスをうまく取りたい(^^;) */
- step = l[num-1]/128;
- for( i=256; (t0=l[num-1]/i)>0 ; i*=2 )
- step -= t0;
- if( step <= 0 ) step = 2;
- else step *= 2;
-
- x0 = get_sp( 0, l, x, a );
- y0 = get_sp( 0, l, y, b );
-
- for( i=1 ; i<=l[num-1] ; i+=step )
- { x1 = get_sp( i, l, x, a );
- y1 = get_sp( i, l, y, b );
-
- line.x0 = x0;
- line.y0 = y0;
- line.x1 = x1;
- line.y1 = y1;
- EGB_connect( EgbPtr, &line );
-
- x0=x1,y0=y1;
- }
- if( i-step < l[num-1] )
- { i = l[num-1];
- x1 = get_sp( i, l, x, a );
- y1 = get_sp( i, l, y, b );
-
- line.x0 = x0;
- line.y0 = y0;
- line.x1 = x1;
- line.y1 = y1;
- EGB_connect( EgbPtr, &line );
- }
- sp_end:
- PI_FREE( l );
-
- return NOERR;
- }
-
-
- /*************************************/
-
- int APL_exec()
- {
- int pen;
-
- pen = cnfg[0].val;
-
- EGB_writePage( EgbPtr, PI_PAGE );
- EGB_writeMode( EgbPtr, EGB_PSET );
-
- /* タイル指定を有効に */
- if( PI_TILEFLG )
- { EGB_tilePattern( EgbPtr, EGB_FORECOL,
- PI_TILE_X, PI_TILE_Y, PI_TILE_PAT );
- EGB_paintMode( EgbPtr, EGB_PAINT_TILE );
- }else
- { EGB_color( EgbPtr, EGB_FORECOL, PI_FORECOL );
- EGB_paintMode( EgbPtr, EGB_PAINT_BETA );
- }
- EGB_penSize( EgbPtr, pen );
-
- /****/
-
- num = WORD( g_para );
- return spline( (Points *)(g_para+2) );
-
- }
-
-